package com.fy.fyspace.common.utils;

import com.fy.fyspace.model.vo.monitor.PerformanceRecordVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 监控数据导出工具类
 * 用于将监控数据导出为Excel文件
 * 
 * @author fy
 * @since 2024-01-01
 */
@Component
@Slf4j
public class MonitorDataExportUtil {

    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 导出性能监控记录到Excel
     */
    public void exportPerformanceRecords(HttpServletResponse response, List<PerformanceRecordVO> records, 
                                       String fileName) throws IOException {
        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("性能监控记录");
            
            // 创建标题行样式
            CellStyle headerStyle = createHeaderStyle(workbook);
            
            // 创建标题行
            Row headerRow = sheet.createRow(0);
            String[] headers = {
                "记录ID", "监控名称", "描述", "类名", "方法名", "请求URI", "请求方法", 
                "客户端IP", "用户代理", "请求参数", "响应结果", "开始时间", "结束时间", 
                "执行时间(ms)", "慢查询阈值(ms)", "是否慢查询", "是否有异常", 
                "异常类型", "异常信息", "创建时间"
            };
            
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
            }
            
            // 填充数据
            int rowNum = 1;
            for (PerformanceRecordVO record : records) {
                Row row = sheet.createRow(rowNum++);
                
                row.createCell(0).setCellValue(record.getRecordId());
                row.createCell(1).setCellValue(record.getMonitorName());
                row.createCell(2).setCellValue(record.getDescription());
                row.createCell(3).setCellValue(record.getClassName());
                row.createCell(4).setCellValue(record.getMethodName());
                row.createCell(5).setCellValue(record.getRequestUri());
                row.createCell(6).setCellValue(record.getRequestMethod());
                row.createCell(7).setCellValue(record.getClientIp());
                row.createCell(8).setCellValue(record.getUserAgent());
                row.createCell(9).setCellValue(record.getRequestParams());
                row.createCell(10).setCellValue(record.getResponseResult());
                row.createCell(11).setCellValue(record.getStartTime() != null ? 
                    record.getStartTime().format(DATE_FORMATTER) : "");
                row.createCell(12).setCellValue(record.getEndTime() != null ? 
                    record.getEndTime().format(DATE_FORMATTER) : "");
                row.createCell(13).setCellValue(record.getExecutionTime());
                row.createCell(14).setCellValue(record.getSlowThreshold());
                row.createCell(15).setCellValue(record.getSlowQuery() ? "是" : "否");
                row.createCell(16).setCellValue(record.getHasException() ? "是" : "否");
                row.createCell(17).setCellValue(record.getExceptionType());
                row.createCell(18).setCellValue(record.getExceptionMessage());
                row.createCell(19).setCellValue(record.getCreateTime() != null ? 
                    record.getCreateTime().format(DATE_FORMATTER) : "");
            }
            
            // 自动调整列宽
            for (int i = 0; i < headers.length; i++) {
                sheet.autoSizeColumn(i);
            }
            
            // 设置响应头
            setResponseHeaders(response, fileName);
            
            // 写入响应流
            workbook.write(response.getOutputStream());
            
            log.info("性能监控记录导出成功 - 记录数: {}", records.size());
            
        } catch (Exception e) {
            log.error("导出性能监控记录失败", e);
            throw new IOException("导出失败: " + e.getMessage());
        }
    }

    /**
     * 导出系统监控数据到Excel
     */
    public void exportSystemMonitorData(HttpServletResponse response, List<Object> data, 
                                      String fileName, String sheetName) throws IOException {
        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet(sheetName);
            
            // 创建标题行样式
            CellStyle headerStyle = createHeaderStyle(workbook);
            
            // 这里可以根据数据类型创建不同的标题行
            // 暂时使用通用的标题行
            Row headerRow = sheet.createRow(0);
            String[] headers = {"监控项", "数值", "单位", "时间"};
            
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
            }
            
            // 填充数据
            int rowNum = 1;
            for (Object item : data) {
                Row row = sheet.createRow(rowNum++);
                // 这里需要根据具体的数据类型来填充
                // 暂时留空，可以根据需要扩展
            }
            
            // 自动调整列宽
            for (int i = 0; i < headers.length; i++) {
                sheet.autoSizeColumn(i);
            }
            
            // 设置响应头
            setResponseHeaders(response, fileName);
            
            // 写入响应流
            workbook.write(response.getOutputStream());
            
            log.info("系统监控数据导出成功 - 数据项数: {}", data.size());
            
        } catch (Exception e) {
            log.error("导出系统监控数据失败", e);
            throw new IOException("导出失败: " + e.getMessage());
        }
    }

    /**
     * 创建标题行样式
     */
    private CellStyle createHeaderStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setBold(true);
        font.setFontHeightInPoints((short) 12);
        style.setFont(font);
        style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        return style;
    }

    /**
     * 设置响应头
     */
    private void setResponseHeaders(HttpServletResponse response, String fileName) {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        
        // 设置文件名
        String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8)
                .replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + encodedFileName + ".xlsx");
        
        // 设置缓存控制
        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Expires", "0");
    }

    /**
     * 导出监控统计数据到Excel
     */
    public void exportMonitorStatistics(HttpServletResponse response, Object statistics, 
                                      String fileName) throws IOException {
        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("监控统计");
            
            // 创建标题行样式
            CellStyle headerStyle = createHeaderStyle(workbook);
            
            // 创建标题行
            Row headerRow = sheet.createRow(0);
            String[] headers = {"统计项", "数值", "单位", "说明"};
            
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
            }
            
            // 这里可以根据具体的统计数据来填充
            // 暂时留空，可以根据需要扩展
            
            // 自动调整列宽
            for (int i = 0; i < headers.length; i++) {
                sheet.autoSizeColumn(i);
            }
            
            // 设置响应头
            setResponseHeaders(response, fileName);
            
            // 写入响应流
            workbook.write(response.getOutputStream());
            
            log.info("监控统计数据导出成功");
            
        } catch (Exception e) {
            log.error("导出监控统计数据失败", e);
            throw new IOException("导出失败: " + e.getMessage());
        }
    }
} 